package practise.alogrithm.introductionToAlogrithm.dataStructures;

import practise.alogrithm.introductionToAlogrithm.TreeBuilder;
import practise.alogrithm.introductionToAlogrithm.TreeNode;

/**
 * Created by Richard on 7/21/2014.
 */
public class BinTreeInVisitorModel implements Acceptor {
    private Visitor visitor ;
    @Override
    public void accept(Visitor visitor) {
        this.visitor = visitor;
    }
    public <T> void visit(TreeNode<T> treeNode){
        visitor.visit(treeNode);
    }

    public <T> void inorder(TreeNode<T> treeNode){
        if(treeNode==null){
            return;
        }

        inorder(treeNode.getLeft());
        visit(treeNode);
        inorder(treeNode.getRight());
    }

    public <T> T leftMost(TreeNode<T> treeNode){
        if(treeNode.getLeft()==null){
            return treeNode.getValue();
        }
        return leftMost(treeNode.getLeft());
    }

    public static void main(String[] args){
        TreeNode<Integer> root = TreeBuilder.createTreeByArrayInWidth(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});
        TreeBuilder.printTreeInWidth(root);
        BinTreeInVisitorModel binTreeSearch = new BinTreeInVisitorModel();
        binTreeSearch.accept(new SimpleTreeNodeVisitor());
        System.out.println();
        System.out.println("In order");
        binTreeSearch.inorder(root);

        System.out.println();
        System.out.println("left most!");
        System.out.println(binTreeSearch.leftMost(root));
    }
}

class SimpleTreeNodeVisitor implements Visitor{

    @Override
    public <T> void visit(TreeNode<T> treeNode) {
        System.out.print("["+treeNode.getValue()+"]");
    }
}

interface Acceptor{
    public void accept(Visitor visitor);
}

interface Visitor{
    public <T> void visit(TreeNode<T> treeNode);
}
